#include "noisegenerator.h"

NoiseGenerator::NoiseGenerator(QObject *parent) :
    QObject(parent)
{
    _vol_ = 0.05;
    _stop_flag = false;
}

NoiseGenerator::~NoiseGenerator()
{
    aoShutdown();
}


void NoiseGenerator::setVolume(double volume)
{
    _vol_ = volume;
}

void NoiseGenerator::genNoise()
{
    aoInit();
    _stop_flag = false;
    double time = 0.1;
    int buf_size = static_cast<int>(fmt.bits/8 * fmt.channels * fmt.rate * time);
    int sample;
    double tm = fmt.rate * time;

    while(!_stop_flag)
    {
        char *buffer = new char[buf_size+1];
        for (int i = 0; i < tm; i++)
        {
            for (int c = 0; c < fmt.channels; c++)
            {
                sample = static_cast<int>(_vol_ * (1 << (fmt.bits - 1)) * (2 * ((qrand()/(double)RAND_MAX) - 0.5)));
                for (int j = 0; j < fmt.bits/8; j++)
                {
                    buffer[fmt.bits/8*i*fmt.channels + fmt.channels*c + j] = sample & 0xff;
                    sample >>= 8;
                }
            }
        }

        ao_play(dev, buffer, buf_size);
        delete[] buffer;
    }
    aoShutdown();
}

void NoiseGenerator::stopNoise()
{
    _stop_flag = true;
}

void NoiseGenerator::aoInit()
{
    ao_initialize();
    driver = ao_default_driver_id();
    memset(&fmt,0,sizeof(ao_sample_format));
    fmt.bits = 16;
    fmt.channels = 2;
    fmt.rate = 44100;
    fmt.byte_format = AO_FMT_LITTLE;

    dev = ao_open_live(driver,&fmt,NULL);
    if(!dev)
    {
        qDebug()<<"NoiseGenerator::err::open_ao_device";
        aoShutdown();
        return;
    }
}

void NoiseGenerator::aoShutdown()
{
    ao_close(dev);
    ao_shutdown();
}
